package icu.yougan.trade.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;


import icu.yougan.trade.entity.User;
import icu.yougan.trade.enums.ErrorMsg;
import icu.yougan.trade.service.Impl.EmailCodeServiceImpl;
import icu.yougan.trade.service.UserService;

import icu.yougan.trade.utils.JwtTokenUtil;
import icu.yougan.trade.vo.R;
import jakarta.validation.Valid;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;

import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.net.URLEncoder;
import java.sql.Timestamp;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import java.io.IOException;
import java.util.Map;

/**
 * 用户相关 控制层
 *
 * @author: YougGan
 * @date: 2024-05-15
 *
 * @changeByLyh
 * @date:2025-02-08
 */
@CrossOrigin
@RestController
@Validated
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService userService;
    @Value("${gitee.giteeClientId}")
    private String giteeClientId;
    @Value("${gitee.giteeClientSecret}")
    private String giteeClientSecret;
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private EmailCodeServiceImpl emailCodeService;
    @Resource
    private AuthenticationManager authenticationManager;
    /**
     * 注册账号
     *
     * @param user 用户信息
     * @return 结果
     */
    @PostMapping("sign-in")
    public R signIn(@RequestBody User user) {
        //System.out.println("注册时获取到的user为："+user);
        if (!emailCodeService.verifyCode(user.getEmail(),
                user.getEmailCode(),
                EmailCodeServiceImpl.CodeType.REGISTER)) {
            return R.fail(ErrorMsg.REGISTER_ERROR);
        }
        if(userService.getUserByEmail(user.getEmail())!=null)
        {
            return R.fail(ErrorMsg.EMAIL_IS_EXIST);
        }
        user.setSignInTime(new Timestamp(System.currentTimeMillis()));
        if (user.getAvatar() == null || "".equals(user.getAvatar())) {
            user.setAvatar("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");
        }
        try{
            userService.userSignIn(user);
            return R.success(user);
        }catch (DuplicateKeyException e)
        {
            return R.fail(ErrorMsg.REGISTER_ERROR);
        }
    }
    // 新增验证码接口
    @PostMapping("/send-code")
    public R sendCode(@RequestBody Map<String, String> params) {
        emailCodeService.sendCode(params.get("email"),
                EmailCodeServiceImpl.CodeType.valueOf(params.get("type")));
        return R.success();
    }

    /**
     * 密码重置
     * @param params
     * @return
     */
    @PostMapping("/reset-password")
    public R resetPassword(@RequestBody Map<String, String> params) {
        String email = params.get("email");
        String newPassword=params.get("newPassword");
        System.out.println("重置密码时获取的email为:"+email+"   新密码为:"+newPassword);
        if (!emailCodeService.verifyCode( email,
                params.get("code"),
                EmailCodeServiceImpl.CodeType.RESET_PWD)) {
            return R.fail(ErrorMsg.PASSWORD_RESET_ERROR);
        }
        User user = userService.getUserByEmail(email);
        System.out.println("重置密码时获取的user为:"+user);
        if (user == null) {
            return R.fail(ErrorMsg.PASSWORD_RESET_ERROR);
        }
        userService.updatePasswordDirectly(user.getId(), newPassword);
        return R.success();
    }
    /**
     * Gitee登录 第三方登录接入
     */
    @RequestMapping("/render")
    public void renderAuth(HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest();
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

    /**
     *
     * @param callback
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/callback")
    public Object login(AuthCallback callback,HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest();
        //获取用户第三方授权信息
        JSONObject jsonObject= JSONUtil.parseObj(authRequest.login(callback),false);
        JSONObject json=JSONUtil.parseObj(jsonObject.get("data"),false);
        //转换为字符串格式
        String accountNum= (String) json.get("username");
        String userPassword="123456";
        String nickName=(String)json.get("nickname");
        // 创建认证上下文
        UserDetails userDetails = userDetailsService.loadUserByUsername(accountNum);
        UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //查看用户是否注册
        User user=userService.getUserByAccountNum(accountNum);
        if(user==null)
        {
            User newUser=new User();
            Byte b=3;
            newUser.setUserStatus(b);
            newUser.setNickname(nickName);
            newUser.setUserPassword(userPassword);
            newUser.setAccountNumber(accountNum);
            newUser.setSignInTime(new Timestamp(System.currentTimeMillis()));
            newUser.setAvatar("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");
            userService.userSignIn(newUser);
            user=newUser;
        }
        if (user.getUserStatus() != null && user.getUserStatus().equals((byte) 1)) {
            return R.fail(ErrorMsg.ACCOUNT_Ban);
        }
        // 生成JWT





























        userDetails = userDetailsService.loadUserByUsername(user.getAccountNumber());
        String token = jwtTokenUtil.generateToken(userDetails);
        response.sendRedirect("http://localhost:8081/#/auth-redirect?token=" + URLEncoder.encode(token, "UTF-8"));
        return null;
    }

    private AuthRequest getAuthRequest() {
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId(giteeClientId)
                .clientSecret(giteeClientSecret)
                .redirectUri("http://localhost:8080/user/callback")
                .build());
    }
    /**
     * 登录
     *
     * @param accountNumber 账号
     * @param userPassword  密码
     * @return 登录结果
     */
    @RequestMapping("login")
    public R login(
            @RequestParam @NotEmpty String accountNumber,
            @RequestParam @NotEmpty String userPassword
    ) {
        try {
            // 手动进行认证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(accountNumber, userPassword)
            );
            // 生成JWT
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            String token = jwtTokenUtil.generateToken(userDetails);
            // 获取完整用户信息
            User user = userService.getUserByAccountNum(accountNumber);
            // 返回用户信息和token
            return R.success(Map.of(
                    "user", user,
                    "token", token, // 前端保存此token
                    "msg", "登录成功" // 添加明确提示
            ));
        }
        catch (AuthenticationException e)
        {
            return R.fail(ErrorMsg.EMAIL_LOGIN_ERROR);
        }
    }

    /**
     * 退出登录
     * @return 结果
     */
    @GetMapping("/logout")
    public R logout() {
        System.out.println("成功退出！");

        return R.success("退出成功");
    }

    /**
     * 获取用户信息
     * @param authentication 认证对象容器
     * @Type user 用户信息
     * @return 用户信息
     */
    @GetMapping("info")
    public R getCurentUser(Authentication authentication) {
        // 直接从安全上下文中获取用户名
        String accountNumber = authentication.getName();
        User user = userService.getUserByAccountNum(accountNumber);
        //System.out.println("获取当前用户的图片信息"+user.getAvatar());
        return R.success(user);
    }

    /**
     * 修改用户公开信息
     *
     * @param user 用户信息
     * @return 修改结果
     */
    @PostMapping("/info")
    public R updateUserPublicInfo(@RequestBody User user) {
        // 从安全上下文中获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return R.fail(ErrorMsg.NOT_LOGIN);
        }
        // 通过用户名获取完整用户信息
        String accountNumber = authentication.getName();
        User currentUser = userService.getUserByAccountNum(accountNumber);
        if (currentUser == null) {
            return R.fail(ErrorMsg.ACCOUNT_NOT_EXIT);
        }
        // 设置当前用户ID
        user.setId(currentUser.getId());
        if (userService.updateUserInfo(user)) {
            return R.success();
        }
        return R.fail(ErrorMsg.SYSTEM_ERROR);
    }


    /**
     * 修改密码
     *
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return
     */
    @GetMapping("/password")
    public R updateUserPassword(
            @RequestParam("oldPassword") String oldPassword,
            @RequestParam("newPassword") String newPassword)
    {
        // 从 SecurityContext 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String accountNumber = authentication.getName();

        User user = userService.getUserByAccountNum(accountNumber);
        if (user == null) {
            return R.fail(ErrorMsg.ACCOUNT_NOT_EXIT);
        }
        if (userService.updatePassword(newPassword, oldPassword, user.getId())) {
            return R.success();
        }
        return R.fail(ErrorMsg.PASSWORD_RESET_ERROR);
    }
}
